/*!
 *	$Id: sdcard.h 256 2011-07-20 07:14:30Z podolski $
 *	$URL: https://versions1.kt.uni-due.de/svn/ktdsp/trunk/sdcard.h $
 *	$Revision: 256 $
 *	$Date: 2011-07-20 09:14:30 +0200 (Mi, 20 Jul 2011) $
 *	$Author: podolski $
 *	@author Lehrstuhl fuer Kommunikationstechnik, Universitaet Duisburg-Essen
 *	@file
 *	@brief SD card driver.
 *
 *	This module allows to write to and read data from an SD card.
 *
 */
 
#ifndef _SDCARD_H_
#define _SDCARD_H_


#include <stm32f4xx.h>

/*************************************
 *************** SD Handle ***********
 *************************************/


#define 		SDhandle 					SPI2
#define 		SdcardHandle				SPI_TypeDef

/**************************************
 *********** TOKENS DEFINITIONS *******
 *************************************/
// data tokens

#define			DATA_START_TOKEN			0xFE
#define			DATA_MULT_WRT_START_TOK		0xFC
#define			DATA_MULT_WRT_STOP_TOK		0xFD

/**************************************
 *********** BLOCK LENGHS  ************
 *************************************/

#define			BLOCKLEN_64				0x0040
#define			BLOCKLEN_128			0x0080
#define			BLOCKLEN_256			0x0100
#define			BLOCKLEN_512			0x0200


/**************************************
 *************** COMMANDS *************
 *************************************/
 
 #define		GO_IDLE_STATE				0x40 //cmd0
 #define		SEND_OP_COND				0x41 //cmd1
 #define		SEND_CSD					0x49 //cmd9
 #define		SEND_CID					0x4a //cmd11
 #define		READ_OCR					0x7a //cmd58
 #define		SEND_STATUS					0x4d //cmd13
 #define		SET_BLOCKLEN				0x50 //cmd16
 #define		WRITE_SINGLE_BLOCK			0x58 //cmd24
 #define		READ_SINGLE_BLOCK			0x51 //cmd17
 #define		ERASE_WR_BLK_START_ADDR		0x60 //cmd32
 #define		ERASE_WR_BLK_END_ADDR		0x61 //cmd33
 #define		ERASE						0x66 //cmd38
 #define		READ_MULTI_BLOCK			0x52 //cmd18
 #define		WRITE_MULTI_BLOCK			0x59 //cmd25
 #define		STOP_TRANSMISSION			0x4b //cmd13
 


/**************************************
 *********** SD CARD RESPONSES*********
 *************************************/

#define			R1						0x00
#define			R1b						0x01
#define			R2						0x02
#define			R3						0x03
#define			NODATA					0x00
#define			MOREDATA				0x01
#define			CARD_IS_BUSY			0x00


/**************************************
 *********** ERROR / SUCCESS CODES*****
 *************************************/
 

typedef enum {
	SD_SUCCESS = 			0x00,
	SD_BLOCK_SET_ERROR=	    0x01,
	SD_RESPONSE_ERROR=	    0x02,
	SD_DATA_TOKEN_ERROR= 	0x03,
	SD_INIT_ERROR=        	0x04,
	SD_CRC_ERROR=         	0x10,
	SD_WRITE_ERROR=      	0x11,
	SD_OTHER_ERROR=       	0x12,
	SD_TIMEOUT_ERROR=     	0xFF,
	SD_FLOATING_BUS=		0xFF,
	
	/*data responses*/
	DATA_ACCEPTED=			0x05,
	DATA_CRC_ERR=			0x0b,
	DATA_WRT_ERR=			0x0d
} SdErrorT;


typedef struct {
	//uint8_t	cid[16]; //CID is not needed - in the contents of this registers are useless for serviceing
	uint8_t	csd[16]; //register contains configuration information required to access the card data
	//uint8_t	ocr[5]; //inf about power supply voltages , default set range is 2,7-3,6 V
	uint8_t	status[2]; //informations about state of the card
} sdRegisters;

void sdcard_reg_init(SdcardHandle *h, sdRegisters *reg);

SdErrorT sdcard_init(SdcardHandle *h, sdRegisters *reg);

void sdcard_get_ocr(SdcardHandle *h, uint8_t *data);

void sdcard_get_cid(SdcardHandle *h, uint8_t *data);

void sdcard_get_csd(SdcardHandle *h, uint8_t *data);

void sdcard_get_status(SdcardHandle *h, uint8_t *data);

SdErrorT sdcard_sector_write(SdcardHandle *h, uint32_t SectorAdress, uint8_t *Buffer);

SdErrorT sdcard_sector_read(SdcardHandle *h, uint32_t SectorAdress, uint8_t *Buffer);

SdErrorT sdcard_sector_erase(SdcardHandle *h, uint32_t StartAddress, uint32_t EndAddress);

SdErrorT sdcard_multiple_write(SdcardHandle *h, uint32_t StartAddress, uint32_t TotalBlocks, uint8_t *Buffer);

SdErrorT sdcard_multiple_read(SdcardHandle *h, uint32_t StartAddress, uint32_t TotalBlocks, uint8_t *Buffer);

#endif //_SDCARD_H_
